from django import forms
from django.contrib.auth import login
from django.db.models import Q
from django_redis import get_redis_connection
from . import constants
from users.models import User
import re

class RegisterForm(forms.Form):
    username = forms.CharField(label='用户名', max_length=20, min_length=5,
                               error_messages={"min_length": "用户名长度要大于5", "max_length": "用户名长度要小于20",
                                               "required": "用户名不能为空"}
                               )
    password = forms.CharField(label='密码', max_length=20, min_length=6,
                               error_messages={"min_length": "密码长度要大于6", "max_length": "密码长度要小于20",
                                               "required": "密码不能为空"}
                               )
    password_repeat = forms.CharField(label='确认密码', max_length=20, min_length=6,
                                      error_messages={"min_length": "密码长度要大于6", "max_length": "密码长度要小于20",
                                                      "required": "密码不能为空"}
                                      )
    mobile = forms.CharField(label='手机号', max_length=11, min_length=11,
                             error_messages={"min_length": "手机号长度有误", "max_length": "手机号长度有误",
                                             "required": "手机号不能为空"})

    sms_code = forms.CharField(label='短信验证码', max_length=6, min_length=6,
                               error_messages={"min_length": "短信验证码长度有误", "max_length": "短信验证码长度有误",
                                               "required": "短信验证码不能为空"})


    def clean_username(self):
        uname = self.cleaned_data.get('username')
        if User.objects.filter(username=uname).exists():
            raise forms.ValidationError('用户名已注册，请重新输入')

        return uname

    def clean_mobile(self):

        tel = self.cleaned_data.get('mobile')
        if not re.match(r"^1[3-9]\d{9}$",tel):
            raise forms.ValidationError('手机号格式错误')

        if User.objects.filter(mobile=tel).exists():
            raise forms.ValidationError('手机号已注册，请重新输入')
        return tel

    def clean(self):
        cleaned_data = super().clean()
        passwd = cleaned_data.get('password')
        passwd_repeat = cleaned_data.get('password_repeat')

        if passwd != passwd_repeat:
            raise forms.ValidationError('两次输入的密码不一致')

        tel = cleaned_data.get('mobile')
        sms_text = cleaned_data.get('sms_code')

        redis_conn = get_redis_connection('verify_codes')

        # 给用户输入的手机号创建一个和redis保存的手机号一样的标记
        sms_fmt = "sms_{}".format(tel).encode('utf8')
        real_sms = redis_conn.get(sms_fmt)

        if (not real_sms) or (sms_text != real_sms.decode('utf8')):
            raise forms.ValidationError('短信验证码错误')



# 登录
class LoginForm(forms.Form):
    user_account = forms.CharField()
    password = forms.CharField(label='密码', max_length=20, min_length=6,
                               error_messages={"min_length": "密码长度要大于6", "max_length": "密码长度要小于20",
                                               "required": "密码不能为空"})
   # g勾选状态
    remember_me = forms.BooleanField(required=False)

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(LoginForm,self).__init__(*args,**kwargs)


    def clean_user_account(self):
        user_info = self.cleaned_data.get('user_account')
        if not user_info:
            raise forms.ValidationError('用户账户不能为空')

        if not re.match(r"^1[3-9]\d{9}$", user_info) and (len(user_info) < 5 or len(user_info) > 20):
            raise forms.ValidationError('用户账号格式不正确,请重新输入')

        return user_info



    def clean(self):
        cleaned_data = super().clean()
        user_info = cleaned_data.get('user_account')        # 用户信息
        passwd = cleaned_data.get('password')           # 密码
        hold_login = cleaned_data.get('remember_me')  # 勾选

        user_queryset = User.objects.filter(Q(mobile=user_info) | Q(username=user_info))
        if user_queryset:
            user = user_queryset.first()
            if user.check_password(passwd):

                if hold_login:
                    self.request.session.set_expiry(constants.USER_SESSION_EXPIRES)
                else:
                    self.request.session.set_expiry(0)

                login(self.request,user)            # login向session中添加SESSION_KEY, 便于对用户进行跟踪:
            else:
                raise forms.ValidationError('密码错误，请重新输入')

        else:
            raise forms.ValidationError('用户账号不存在，请重新输入')
